package com.yang.service.impl;


import com.yang.constant.ConfiConstant;
import com.yang.dao.RegisterDao;
import com.yang.entity.UserEntity;
import com.yang.pojo.UploadUser;
import com.yang.service.UploadService;
import com.yang.util.SecurityUtil;
import com.yang.util.SnowFlake;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jboss.logging.Logger;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.regex.Pattern;

@Service
public class UploadServiceImpl implements UploadService {

    private static String[] titleName = {"账号","密码","用户名","身份"};
    private static Logger logger = Logger.getLogger(UploadServiceImpl.class);

    @Resource
    RegisterDao registerDao;
    @Override
    public Map<String, Object> readExcel(List<MultipartFile> multipartFileList) {
        Map<String,Object> map = new HashMap<String,Object>();
        if(multipartFileList.isEmpty()){
            map.put("status","error");
            map.put("info","上传空文件");
            return map;
        }
        for(MultipartFile multipartFile :multipartFileList){
            File file = multFileTransferToFile(multipartFile);
            List<UserEntity> userEntityList = null;
            if(file == null){
                logger.info("file is null");
                continue;
            }
            String path = file.getAbsolutePath();
            if(StringUtils.isBlank(path)){
                logger.info("file path is blank");
                continue;
            }
            if(Pattern.matches("(.*)\\."+ConfiConstant.XLS_POSTFIX,path)){
                logger.info("path1="+path);
                userEntityList = readXls(file);
            }else if(Pattern.matches("(.*)\\."+ConfiConstant.XLSX_POSTFIX,path)){
                logger.info("path2="+path);
                userEntityList = readXlsx(file);
            }else{
                logger.error("error filePath = "+path);
            }
            for(UserEntity userEntity :userEntityList){
                logger.info("userEntity = "+userEntity);
                registerDao.saveUser(userEntity);
            }

        }
        map.put("status","succeed");
        return map;
    }

    /**
     * 把MultipartFile转成File
     * @author yang
     * @param multipartFile
     * @return
     */
    private File multFileTransferToFile(MultipartFile multipartFile){
        String fileName = multipartFile.getOriginalFilename();
        if(StringUtils.isBlank(fileName)){
            logger.info("fileName is null");
            return null;
        }
        logger.info("fileName="+fileName);
        String split[] = multipartFile.getOriginalFilename().split("\\.");
        System.out.println(multipartFile.getOriginalFilename());
        SnowFlake snowFlake = new SnowFlake(3,0);
        String filePath = ConfiConstant.File_name + snowFlake.getId() + "." + split[split.length - 1];
        File tempFile = new File(filePath);
        if (!tempFile.exists()) {
            tempFile.mkdirs();
        }
        try {
            multipartFile.transferTo(tempFile);
        } catch (IOException e){
            e.printStackTrace();
            return null;
        }
        return tempFile;
    }

    private List<UserEntity> readXls(File file){
        InputStream inputStream = null;
//        HSSFWorkbook hssfWorkbook = null;
        Workbook hssfWorkbook = null;
        List<UserEntity> userEntityList = new ArrayList<UserEntity>();
        try {
            inputStream = new FileInputStream(file);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        try {
//            hssfWorkbook = new HSSFWorkbook(inputStream);
            hssfWorkbook = new XSSFWorkbook(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        for (int numSheet = 0; numSheet < hssfWorkbook.getNumberOfSheets(); numSheet++) {
//            HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(numSheet);
              Sheet hssfSheet = hssfWorkbook.getSheetAt(numSheet);
            if (hssfSheet == null) {
                continue;
            }
            int rowNum = 1;
            while (rowNum <= hssfSheet.getLastRowNum()) {
//                HSSFRow hssfRow = hssfSheet.getRow(rowNum);
                Row hssfRow = hssfSheet.getRow(rowNum);
                if (!checkRowEmpty(hssfRow)) {
                    logger.info("row is empty");
                    rowNum++;
                    continue;
                }
                String num = getValue(hssfRow.getCell(0));
                if(!registerDao.judgeEmilExist(num)){
                    rowNum++;
                    continue;
                }
                UserEntity userEntity = new UserEntity();
                userEntity.setNum(num);
                userEntity.setPassword(transformPassword(getValue(hssfRow.getCell(1))));
                userEntity.setUserName(getValue((hssfRow.getCell(2))));
                userEntity.setIdentification(getValue(hssfRow.getCell(3)));
                SnowFlake snowFlake = new SnowFlake(3,3);
                userEntity.setId(snowFlake.getId());
                userEntityList.add(userEntity);
                logger.info("readXlsUserEntity="+userEntity);
                rowNum++;
            }
        }
        return userEntityList;
    }
    private List<UserEntity> readXlsx(File file){
        InputStream is = null;
        XSSFWorkbook xssfWorkbook = null;
        try {
            is = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            xssfWorkbook = new XSSFWorkbook(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        List<UserEntity> userEntityList = new ArrayList<UserEntity>();
        logger.info("xssfWorkbook.getNumberOfSheets()="+xssfWorkbook.getNumberOfSheets());
        for (int numSheet = 0; numSheet < xssfWorkbook.getNumberOfSheets(); numSheet++) {
            logger.info("numSheet = "+numSheet);
            XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(numSheet);
            if (xssfSheet == null) {
                logger.info("xssfSheet == null");
                continue;
            }

            int rowNum = 1;
            while (rowNum <= xssfSheet.getLastRowNum()) {
                logger.info("rowNum = "+rowNum);
                XSSFRow xssfRow = xssfSheet.getRow(rowNum);
                if (!checkRowEmpty(xssfRow)) {
                    logger.info("row is empty");
                    rowNum++;
                    continue;
                }
                String num = getValue(xssfRow.getCell(0));
                if(!registerDao.judgeEmilExist(num)){
                    rowNum++;
                    continue;
                }
                UserEntity userEntity = new UserEntity();
                userEntity.setNum(num);
//                UserEntity userEntity = new UserEntity();
//                userEntity.setNum(getValue(xssfRow.getCell(0)));
                userEntity.setPassword(transformPassword(getValue(xssfRow.getCell(1))));
                userEntity.setUserName(getValue(xssfRow.getCell(2)));
                userEntity.setIdentification(getValue(xssfRow.getCell(3)));
                SnowFlake snowFlake = new SnowFlake(3,3);
                userEntity.setId(snowFlake.getId());
                userEntityList.add(userEntity);
                logger.info("readXlsxUserEntity="+userEntity);
                rowNum++;
            }
        }
        return userEntityList;
    }

    private String transformPassword(String password){
        try {
            password = SecurityUtil.encryptPassword(password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return password;
    }

    private boolean checkRowEmpty(Row row){
        boolean check = true;
        if(row == null){
            logger.info("row == null");
            return false;
        }
        if(row.getLastCellNum() != titleName.length){
            logger.info("row.getLastCellNum()="+row.getLastCellNum());
            logger.info("row.getLastCellNum() != titleName.length-1");
            return false;
        }
        for (int cellNum = 0; cellNum < row.getLastCellNum(); cellNum++) {
            if (row.getCell(cellNum, Row.RETURN_BLANK_AS_NULL) == null) {
                logger.info("have null cell");
                return false;
            }
        }
        return check;

    }
    private static String getValue(Cell cell) {
        String cellValue = "";
        if (cell == null) {
            return "";
        }
        switch (cell.getCellType()) {
            case XSSFCell.CELL_TYPE_STRING:
                cellValue = cell.getStringCellValue();
                if (cellValue.trim().equals("") || cellValue.trim().length() <= 0)
                    cellValue = null;
                break;
            case XSSFCell.CELL_TYPE_NUMERIC:
                String num = String.valueOf(cell.getNumericCellValue());
                BigDecimal bd = new BigDecimal(num);
                String numPoint = bd.toPlainString();
                String ss[] = numPoint.split("\\.");
                cellValue = ss[0];
                break;
            case XSSFCell.CELL_TYPE_FORMULA:
                cell.setCellType(XSSFCell.CELL_TYPE_NUMERIC);
                cellValue = String.valueOf(cell.getNumericCellValue());
                break;
            case XSSFCell.CELL_TYPE_BLANK:
                cellValue = "";
                break;
            case XSSFCell.CELL_TYPE_BOOLEAN:
                break;
            case XSSFCell.CELL_TYPE_ERROR:
                break;
            default:
                break;
        }
        return cellValue;
    }
}
